﻿using System;
using System.ComponentModel;
using System.Reflection;

namespace Moonlite.Data.Configuration
{
    /// <summary>
    /// Provides extension methods for the <see cref="System.Reflection.PropertyInfo"/> class.
    /// </summary>
    internal static class PropertyInfoExtensions
    {
        private static TypeConverter converter;
        private static Type type;
        private static string propertyName;

        /// <summary>
        /// Creates the type converter.
        /// </summary>
        private static void CreateConverter()
        {
            if (converter == null)
            {
                if (type.IsEnum)
                {
                    converter = new GenericEnumConverter(type);
                }
                else if (!type.IsSubclassOf(typeof(ConfigurationElement)))
                {
                    converter = TypeDescriptor.GetConverter(type);
                    if (((converter == null) || !converter.CanConvertFrom(typeof(string))) || !converter.CanConvertTo(typeof(string)))
                    {
                        throw new TypeConversionException(string.Format("Unable to find a converter that supports conversion to/from string for the property '{0}' of type '{1}'.", new object[] { propertyName, type.Name }));
                    }
                }
            }
        }

        /// <summary>
        /// Converts the specified string to a property info object.
        /// </summary>
        /// <param name="info">The property info object to extend.</param>
        /// <param name="name">The type name to convert to a property info.</param>
        /// <returns>The converted object.</returns>
        public static object FromString(this PropertyInfo info, string name)
        {
            type = info.GetType();
            propertyName = info.Name;
            if (converter == null)
            {
                CreateConverter();
            }

            object @object = null;
            try
            {
                @object = converter.ConvertFromInvariantString(name);
            }
            catch (Exception exception)
            {
                throw new TypeConversionException(string.Format("The value of property '{0}' cannot be parsed. The error is {1}", new object[] { name, exception.Message }));
            }

            return @object;
        }
    }
}
